ถ้าคุณดูเอกสารนี้บน Github ให้กด Ctrl+F เพื่อไปยังหัวข้อที่สนใจ (ที่บอกมาจาก My Portfolio Website)
library(knitr) # ใช้สำหรับรันโค้ด R ที่ฝังในเอกสาร Markdown / LaTeX
library(tidyverse) # แพ็คเกจที่รวบรวมเครื่องใช้จัดการข้อมูล และนำเสนอข้อมูล
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.2 ✔ tibble 3.2.1
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.0.4
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
diamonds |> glimpse() # โครงสร้างตาราง diamonds กี่แถว กี่คอลัมน์ ประเภทคอลัมน์ แต่ละคอลัมน์หน้าตาเป็นยัง
## Rows: 53,940
## Columns: 10
## $ carat <dbl> 0.23, 0.21, 0.23, 0.29, 0.31, 0.24, 0.24, 0.26, 0.22, 0.23, 0.…
## $ cut <ord> Ideal, Premium, Good, Premium, Good, Very Good, Very Good, Ver…
## $ color <ord> E, E, E, I, J, J, I, H, E, H, J, J, F, J, E, E, I, J, J, J, I,…
## $ clarity <ord> SI2, SI1, VS1, VS2, SI2, VVS2, VVS1, SI1, VS2, VS1, SI1, VS1, …
## $ depth <dbl> 61.5, 59.8, 56.9, 62.4, 63.3, 62.8, 62.3, 61.9, 65.1, 59.4, 64…
## $ table <dbl> 55, 61, 65, 58, 58, 57, 57, 55, 61, 61, 55, 56, 61, 54, 62, 58…
## $ price <int> 326, 326, 327, 334, 335, 336, 336, 337, 337, 338, 339, 340, 34…
## $ x <dbl> 3.95, 3.89, 4.05, 4.20, 4.34, 3.94, 3.95, 4.07, 3.87, 4.00, 4.…
## $ y <dbl> 3.98, 3.84, 4.07, 4.23, 4.35, 3.96, 3.98, 4.11, 3.78, 4.05, 4.…
## $ z <dbl> 2.43, 2.31, 2.31, 2.63, 2.75, 2.48, 2.47, 2.53, 2.49, 2.39, 2.…
ตาราง diamonds เป็นชุดข้อมูลเกี่ยวกับเพชรที่มีคอลัมน์หลากหลาย
พร้อมข้อมูลคุณสมบัติที่ ใช้กำหนดราคาเพชร มาดูแต่ละคอลัมน์และความหมายของมัน:
| Cols | Description | Type |
|---|---|---|
| carat | น้ำหนักของเพชร มีหน่วยเป็น “กะรัต” (carats) หน่วยวัดน้ำหนักเพชร | Numeric |
| cut | ระดับคุณภาพการเจียระไน (cut quality) เช่น Fair, Good, Very Good, Premium, Ideal (เรียงจากต่ำไปสูง) | Ordered Factor |
| color | สีของเพชร (D ถึง J โดยที่ D คือใสที่สุด) | Ordered Factor |
| clarity | ระดับความใสของเพชร โดยดูจากตำหนิหรือจุดบกพร่อง (I1, SI2, SI1, VS2, VS1, VVS2, VVS1, IF เรียงจากตำหนิชัดเจนถึงไม่มีเลย) | Ordered Factor |
| depth | อัตราส่วนระหว่างความลึกของเพชรกับเส้นผ่านศูนย์กลางเฉลี่ย มีหน่วยเป็นเปอร์เซ็นต์ (%): (z / mean(x, y)) * 100 | Numeric |
| table | ความกว้างของโต๊ะเพชร (ส่วนเรียบด้านบนของเพชร) เทียบกับเส้นผ่านศูนย์กลางเฉลี่ย มีหน่วยเป็นเปอร์เซ็นต์ (%) | Numeric |
| price | ราคาของเพชร มีหน่วยเป็นดอลลาร์สหรัฐ | Integer |
| x | ความยาว (length) ของเพชรในหน่วยมิลลิเมตร | Numeric |
| y | ความกว้าง (width) ของเพชรในหน่วยมิลลิเมตร | Numeric |
| z | ความลึก (depth) ของเพชรในหน่วยมิลลิเมตร | Numeric |
ขยายความหมาย: depth : ( z / mean(x, y)) * 100
diamonds |> head() # ดู 6 แถวแรก(ไม่รวมหัวตาราง)
diamonds |> tail() # ดู 6 แถวท้าย(ไม่รวมหัวตาราง)
diamonds |> distinct() |> count() != diamonds |> count() # ตรวจสอบว่ามีแถวซ้ำกันไหม TRUE มี, False ไม่มี
## n
## [1,] TRUE
ดูเฉพาะแถวที่ซ้ำ
diamonds |>
group_by(across(everything())) |> # group_by(across(everything())) คือการ group โดยใช้ทุกคอลัมน์
filter(n() > 1) # เลือกเฉพาะกลุ่มที่มีแถวมากกว่า 1 ⇒ นั่นคือแถวที่ซ้ำกัน
ดูเฉพาะแถวที่ไม่ซำ (ไม่รวมแถวซ้ำ)
diamonds |>
group_by(across(everything())) |> # group_by(across(everything())) คือการ group โดยใช้ทุกคอลัมน์
filter(n() == 1) # เลือกเฉพาะแถวที่ไม่ซ้ำกันเท่านั้น
# ดูเฉพาะแถวที่ซ้ำว่ามีกี่แถว แต่ละแถวซ้ำกันกี่ครั้ง
diamonds |>
group_by(across(everything())) |>
tally() |>
filter(n > 1) # แสดงเฉพาะแถวที่ซ้ำ
ลบเฉพาะแถวซ้ำ แต่ยังคงไว้แค่แถวแรกไว้
diamonds |> distinct()
เลือกแถวที่มีค่า NA อย่างน้อย 1 คอลัมน์
diamonds |> filter(if_any(everything(), is.na))
เลือกคอลัมน์ที่มี NA อย่างน้อย 1 แถว
diamonds |> select(where(~ any(is.na(.))))
ลบแถวซ้ำ
prep_diamonds <- diamonds |> distinct()
prep_diamonds
prep_diamonds |> distinct() |> count() != prep_diamonds |> count() # ตรวจสอบว่ามีแถวซ้ำกันไหม TRUE มี, False ไม่มี
## n
## [1,] FALSE
custom_theme <- theme_linedraw() +
theme(
# Darker plot title
plot.title = element_text(
face = "bold",
size = 16,
color = "black",
margin = margin(b = 10)
),
# Darker subtitle
plot.subtitle = element_text(
size = 12,
color = "#2F4F4F", # Dark slate gray
margin = margin(b = 15)
),
# Darker caption
plot.caption = element_text(
size = 8,
color = "#4A4A4A", # Darker gray
margin = margin(t = 10)
),
# Darker axis titles
axis.title = element_text(
size = 11,
color = "#1C1C1C", # Very dark gray
face = "bold"
),
# Darker axis text
axis.text = element_text(
size = 9,
color = "#2F4F4F" # Dark slate gray
),
# Customize facet labels
strip.text = element_text(
face = "bold",
size = 10,
color = "white"
),
strip.background = element_rect(
fill = "#2F4F4F", # Dark slate gray
color = "black"
),
# Darker panel elements
panel.grid.major = element_line(
color = "#BEBEBE", # Medium gray
size = 0.3
),
panel.grid.minor = element_line(
color = "#D3D3D3", # Light gray
size = 0.2
),
panel.border = element_rect(
color = "black",
size = 0.8
),
# Add margin around the plot
plot.margin = margin(15, 15, 15, 15),
# Darker background
panel.background = element_rect(
fill = "white"
)
)
| Price Range ($) | Number of Diamonds |
|---|---|
| 0-500 | 1745 |
| 500-1000 | 12725 |
| 1000-1500 | 5463 |
| 1500-2000 | 4194 |
| 2000-2500 | 3332 |
| 2500-3000 | 2789 |
| 3000-3500 | 2159 |
| 3500-4000 | 2056 |
| 4000-4500 | 2470 |
| 4500-5000 | 2183 |
prep_diamonds %>%
ggplot(aes(price)) +
geom_density(fill = "#4682B4", alpha = 0.7) +
custom_theme +
theme(plot.background = element_rect(fill = "#f5e19f")) +
labs(title = "Price Distribution of Diamonds",
subtitle = "The $500-$1000 price range has the largest number of diamonds.",
caption = "Source: ggplot Package",
x = "Diamond Price Range",
y = "Density")
prep_diamonds %>%
ggplot(aes(price)) +
geom_density(fill = "#4682B4", alpha = 0.7) + # Steelblue with higher opacity
custom_theme +
theme(plot.background = element_rect(fill = "#f5e19f")) +
labs(title = "Price Distribution of Diamonds",
subtitle = "Sub-diagram of diamond price groups, divided by cut",
caption = "Source: ggplot Package",
x = "Diamond Price Range",
y = "Density") +
facet_wrap(~ cut)
prep_diamonds %>%
filter(depth > 60) %>% # Interested in the balance value of
# the diamond shape of more than 60%
ggplot(aes(cut, depth, fill = cut)) +
geom_boxplot() +
custom_theme +
theme(plot.background = element_rect(fill = "#f5e19f")) +
labs(
title = "Depth Distribution Across Diamond Cut Quality",
subtitle = "Comparing Depth Values for 'Fair', 'Good', 'Very Good', 'Premium',
and 'Ideal' Cuts",
caption = "Source: ggplot2 Diamonds Dataset",
x = "Cut Quality",
y = "Depth Percentage (%)"
)
prep_diamonds %>%
filter(depth > 50) %>%
ggplot(aes(depth, price, color = color)) +
geom_point() +
facet_wrap(~ cut) +
custom_theme +
theme(plot.background = element_rect(fill = "#f5e19f")) +
labs(
title = "Dist. of Diamond Shapes with Prices by Diamond Color",
subtitle = "Provided by Cut Quality",
caption = "Source: ggplot2 Diamonds Dataset",
x = "Depth Percentage (%)",
y = "Price ($USD)"
)
ขอเสริมข้อ 3) Depth Distribution Across Diamond Cut Quality.
จาก chart ที่แสดง boxplot ความสัมพันธ์ระหว่าง **depth** (ความลึกของเพชร) และ **cut** (คุณภาพการเจียระไนของเพชร) เราสามารถตั้งชื่อ `labs` ดังนี้:
- **Title**
- "Depth Distribution Across Diamond Cut Quality"
- (แสดงการกระจายตัวของความลึกในแต่ละระดับคุณภาพการเจียระไน)
- **Subtitle**:
- "Comparing Depth Values for 'Fair', 'Good', 'Very Good', 'Premium', and 'Ideal' Cuts"
- (เปรียบเทียบค่าความลึกในแต่ละคุณภาพการเจียระไน)
- **Caption**:
- "Source: ggplot2 Diamonds Dataset"
- (ระบุแหล่งข้อมูลจาก dataset)
- **X**:
- "Cut Quality"
- (แสดงคุณภาพการเจียระไน)
- **Y**:
- "Depth Percentage (%)"
- (ระบุสัดส่วนความลึกของเพชร)
prep_diamonds %>%
filter(
clarity %in% c("VS1", "VVS2", "VVS1", "IF"),
color %in% c("G", "E", "F"),
cut %in% c("Ideal", "Premium", "Very Good")
) %>%
ggplot(aes(carat, price, col = clarity)) +
geom_point() +
geom_smooth(method = "lm", se = FALSE, col = "red") +
facet_grid(color ~ cut) +
custom_theme +
theme(plot.background = element_rect(fill = "#f5e19f")) +
labs(
title = "Correlation Between Carat and Diamond Price",
subtitle = "The overall correlation coefficient is 0.9215913.",
caption = "Source: ggplot2 Diamonds Dataset",
x = "Weigth (Carats)",
y = "Price ($USD)"
)
## `geom_smooth()` using formula = 'y ~ x'